Skip to content

fix(intcomma): handle scientific notation for large/small floats - #443

Open
Jah-yee wants to merge 1 commit into
python-humanize:mainfrom
Jah-yee:fix-intcomma-scientific-notation
Open

Jah-yee wants to merge 1 commit into
python-humanize:mainfrom
Jah-yee:fix-intcomma-scientific-notation

Conversation

@Jah-yee

@Jah-yee Jah-yee commented Oct 5, 2026

Copy link
Copy Markdown

Summary

Fixes #431 — intcomma() returns scientific notation for floats of 1e16 and above (and very small floats like 1e-5), with no commas added.

Root cause: Python's repr() switches to scientific notation for floats with magnitude >= 1e15 or <= 1e-5. The f"{value:,}" format specifier uses repr() internally, so the comma formatting is never applied to the exponent form.

Fix: When ndigits is None and the float is a whole number, format as int to avoid trailing .0. When the float would be formatted in scientific notation, use Decimal for a proper decimal representation before applying commas.

Before:

>>> intcomma(1e16)
'1e+16'
>>> intcomma(1.5e20)
'1.5e+20'

After:

>>> intcomma(1e16)
'10,000,000,000,000,000'
>>> intcomma(1.5e20)
'150,000,000,000,000,000,000'

Files changed:

  • src/humanize/number.py: Fixed intcomma() to handle scientific notation in float repr

Black formatting applied per pre-commit.ci requirements.
@Jah-yee
Jah-yee force-pushed the fix-intcomma-scientific-notation branch from 720f234 to 6da0066 Compare October 6, 2026 08:43

@rmz-oz rmz-oz left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this drops the .0 from every whole float: intcomma(1.0) is now '1' and 1234.0 gives '1,234', but #431 expects '10,000,000,000,000,000.0'. fwiw #432 keeps both the .0 and the sign by going through f"{Decimal(str(value)):,f}". no tests for the new branches either.

Comment thread src/humanize/number.py
elif (
isinstance(value, float)
and value != 0
and (abs(value) >= 1e15 or abs(value) <= 1e-5)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

repr already switches to an exponent below 1e-4, so with this bound intcomma(5e-5) and intcomma(1.5e-5) still come back as '5e-05' and '1.5e-05'.

Comment thread src/humanize/number.py
int_part, dec_part = formatted.split(".")
dec_part = dec_part.rstrip("0")
if dec_part:
result = f"{int(int_part):,}.{dec_part}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int("-0") is 0, so small negatives lose the sign here: intcomma(-1e-5) gives '0.00001' and intcomma(-2.5e-7) gives '0.00000025'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

intcomma returns scientific notation for large floats

2 participants